using Sidewinder.Core.Interfaces.Entities;

namespace Wolfpack.Contrib.Tests.Publishers.Deployment
{
    using Core.Testing.Bdd;
    using NUnit.Framework;
    using StoryQ;

    public class DeploymentPublisherTests : BddFeature
    {
        protected override Feature DescribeFeature()
        {
            return new Story("Testing the deployment publisher")
                .InOrderTo("Ensure the component works correctly")
                .AsA("client component or system")
                .IWant("To ensure the nuget package is downloaded and distributed correctly into the installation folder");
        }

        [Test]
        [Category("Unit")]
        public void DefaultConfigurationValues()
        {
            using (var domain = new DeploymentPublisherDomain())
            {
                Feature.WithScenario("Ensure all optional configuration parameters have expected default values")
                    .Given(domain.TheComponentConfig_IsUsed, "deployment1.castle.config")
                        .And(domain.TheAgentIsStarted)
                    .When(domain.TheDeploymentComponent_IsResolved, "deployment1")
                    .Then(domain.ThrewNoException)
                        .And(domain.TheConflictResolutionPropertyShouldBe_, ConflictResolutionTypes.Overwrite)
                    .ExecuteWithReport();
            }
        }

        [Test]
        [Category("Unit")]
        public void ExpectedConfigurationValues()
        {
            using (var domain = new DeploymentPublisherDomain())
            {
                Feature.WithScenario("Ensure configuration parameters have expected values")
                    .Given(domain.TheComponentConfig_IsUsed, "deployment2.castle.config")
                        .And(domain.TheAgentIsStarted)
                    .When(domain.TheDeploymentComponent_IsResolved, "deployment2")
                    .Then(domain.ThrewNoException)
                        .And(domain.TheConflictResolutionPropertyShouldBe_, ConflictResolutionTypes.Ask)
                    .ExecuteWithReport();
            }
        }

        [Test]
        [Category("Unit")]
        public void PostSuccessfulDownload()
        {
            using (var domain = new DeploymentPublisherDomain())
            {
                Feature.WithScenario("New package detected and downloaded successfully")
                    .Given(domain.TheDownloadFolder, "TestDownload")
                        .And(domain.TheAgentIsStarted)
                    .When(domain.ThePublisherIsCalled)
                    .Then(domain.ThereShouldBe_HealthCheckNotificationsReceived, 1)
                        .And(domain.TheNotificationRecievedAtIndex_ShouldHaveResult_, 1, true)
                        .And(domain.TheCheckNotificationTagShouldBeTheSameAsTheTriggerMessageTag)
                    .ExecuteWithReport();
            }
        }

        [Test]
        [Category("Unit")]
        public void TriggerNotificationHasACriticalFailure()
        {
            using (var domain = new DeploymentPublisherDomain())
            {
                Feature.WithScenario("The trigger notification has a critical failure")
                    .Given(domain.TheDownloadFolder, "TestDownload")
                        .And(domain.TheTriggerNotificationHasACriticalFailure)
                        .And(domain.TheAgentIsStarted)
                    .When(domain.ThePublisherIsCalled)
                    .Then(domain.TheUpdaterShouldNotHaveBeenCalled)
                    .ExecuteWithReport();
            }
        }

        [Test]
        [Category("Unit")]
        public void TriggerNotificationResultFailure()
        {
            using (var domain = new DeploymentPublisherDomain())
            {
                Feature.WithScenario("The trigger notification result indicates failure")
                    .Given(domain.TheDownloadFolder, "TestDownload")
                        .And(domain.TheTriggerNotificationIndicatesFailure)
                        .And(domain.TheAgentIsStarted)
                    .When(domain.ThePublisherIsCalled)
                    .Then(domain.TheUpdaterShouldNotHaveBeenCalled)
                    .ExecuteWithReport();
            }
        }
    }
}